//==============================================================================
#define 	USART_C
#include	"Myincludes.h"
//==============================================================================
#ifndef USE_USART1
#ifndef USE_USART2
#ifndef USE_USART3
#error "no define USE_USARTx"
#endif
#endif
#endif
//==============================================================================

//==============================================================================
void USART_Config(USART_TypeDef *mUsart,u32 mBaud,u16 mWordLength,u16 mStopBits,u16 mParity)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	DMA_Channel_TypeDef *tDmaChannel;
	GPIO_TypeDef *tGpioTx,*tGpioRx;
	u16 tPinTx,tPinRx;
	u32  tRccDma;
    USART_StructType *tStruct;
    u8 tUsartIrqChanel,tDmaIrqChannel;

#if(1==USE_USART1)
	if(USART1 == mUsart)
	{
		tRccDma = RCC_AHBPeriph_DMA1;
		tGpioTx = GPIOA;
		tPinTx = GPIO_Pin_9;
		tGpioRx = GPIOA;
		tPinRx = GPIO_Pin_10;
		tDmaChannel = DMA1_Channel4;
		tStruct = &USART1_TxStruct;
		tUsartIrqChanel = USART1_IRQn;
		tDmaIrqChannel = DMA1_Channel4_IRQn;

		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 
	}
#endif

#if(1==USE_USART2)
	if(USART2 == mUsart)
	{
		tRccDma = RCC_AHBPeriph_DMA1;
		tGpioTx = GPIOA;
		tPinTx = GPIO_Pin_2;
		tGpioRx = GPIOA;
		tPinRx = GPIO_Pin_3;
		tStruct = &USART2_TxStruct;
		tUsartIrqChanel = USART2_IRQn;
		tDmaChannel = DMA1_Channel7;
		tDmaIrqChannel=DMA1_Channel7_IRQn;

		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
	}
#endif

#if(1==USE_USART3)
	if(USART3 == mUsart)
	{
		tRccDma = RCC_AHBPeriph_DMA1;
		tGpioTx = GPIOB;
		tPinTx = GPIO_Pin_10;
		tGpioRx = GPIOB;
		tPinRx = GPIO_Pin_11;
		tStruct = &USART3_TxStruct;
		tUsartIrqChanel = USART3_IRQn;
		tDmaChannel = DMA1_Channel2;
		tDmaIrqChannel = DMA1_Channel2_IRQn;

		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	}
#endif
	//RCC
	RCC_AHBPeriphClockCmd(tRccDma, ENABLE);
	//GPIO
	GPIO_InitStructure.GPIO_Pin = tPinTx;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(tGpioTx, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = tPinRx;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(tGpioRx, &GPIO_InitStructure);
	//USART
    USART_Cmd(mUsart, DISABLE);
    USART_DeInit(mUsart);
	USART_InitStructure.USART_BaudRate = mBaud;
	USART_InitStructure.USART_WordLength = mWordLength;
	USART_InitStructure.USART_StopBits = mStopBits;
	USART_InitStructure.USART_Parity = mParity;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(mUsart, &USART_InitStructure);
	//DMA
    DMA_Cmd(tDmaChannel, DISABLE);
	DMA_DeInit(tDmaChannel);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&mUsart->DR);
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)tStruct->Buf;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_InitStructure.DMA_BufferSize = USART_BUF_SIZE;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(tDmaChannel, &DMA_InitStructure);
	//USART interrupt
	NVIC_InitStructure.NVIC_IRQChannel = tUsartIrqChanel;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	USART_ITConfig(mUsart, USART_IT_RXNE, ENABLE);
	//DMA interrupt
	NVIC_InitStructure.NVIC_IRQChannel = tDmaIrqChannel;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	DMA_ITConfig(tDmaChannel, DMA_IT_TC, ENABLE);
	//enable
    USART_Cmd(mUsart, ENABLE);
	USART_DMACmd(mUsart, USART_DMAReq_Tx, ENABLE);
}
void USART_TxStart(USART_TypeDef *mUsart)
{
    USART_StructType *tStruct;
    DMA_Channel_TypeDef *tDMAChannel;

#if(1==USE_USART1)
	if(USART1 == mUsart)
	{
		tStruct = &USART1_TxStruct;
		tDMAChannel = DMA1_Channel4;
	}
#endif

#if(1==USE_USART2)
	if(USART2 == mUsart)
	{
		tStruct = &USART2_TxStruct;
		tDMAChannel = DMA1_Channel7; 
	}
#endif

#if(1==USE_USART3)
	if(USART3 == mUsart)
	{
		tStruct = &USART3_TxStruct;
		tDMAChannel = DMA1_Channel2; 
	}
#endif

	if(0 == tStruct->Size) return; 

	tStruct->TxRunning = 1;

	DMA_SetCurrDataCounter(tDMAChannel, tStruct->Size);
	DMA_Cmd(tDMAChannel, ENABLE);
}
void USART_RxStart(USART_TypeDef *mUsart)
{
    USART_StructType *tStruct;

#if(1==USE_USART1)
	if(USART1 == mUsart) tStruct = &USART1_RxStruct;
#endif

#if(1==USE_USART2)
	if(USART2 == mUsart) tStruct = &USART2_RxStruct;
#endif

#if(1==USE_USART3)
	if(USART3 == mUsart) tStruct = &USART3_RxStruct;
#endif

	tStruct->Timeout = 0;
	tStruct->Count=0;
	tStruct->RxComplete = 0;
}
//USART_RxTimeoutIrq place in 1ms interrupt function
void USART_RxTimeoutIrq(USART_TypeDef *mUsart)
{
    USART_StructType *tStruct;

#if(1==USE_USART1)
	if(USART1 == mUsart) tStruct = &USART1_RxStruct;
#endif

#if(1==USE_USART2)
	if(USART2 == mUsart) tStruct = &USART2_RxStruct;
#endif

#if(1==USE_USART3)
	if(USART3 == mUsart) tStruct = &USART3_RxStruct;
#endif

	if(0 == tStruct->RxComplete)
	{
		if(tStruct->Count>0)
		{
			tStruct->Timeout++;

			if(USART_TIMEOUT == tStruct->Timeout)
			{
				tStruct->RxComplete = 1;
			}
		}
	}
}
void USART_RxIrq(USART_TypeDef *mUsart)
{
	u8 tData;
    USART_StructType *tStruct;

#if(1==USE_USART1)
	if(USART1 == mUsart) tStruct = &USART1_RxStruct;
#endif

#if(1==USE_USART2)
	if(USART2 == mUsart) tStruct = &USART2_RxStruct;
#endif

#if(1==USE_USART3)
	if(USART3 == mUsart) tStruct = &USART3_RxStruct;
#endif

	if(USART_GetITStatus(mUsart, USART_IT_RXNE) != RESET)
	{
		tData = mUsart->DR;

		if(0 == tStruct->RxComplete)
		{
			tStruct->Timeout = 0; 
			if(tStruct->Count < USART_BUF_SIZE)
			{
				tStruct->Buf[tStruct->Count++] = tData;
			}
		}
	}
}
//==============================================================================

//==============================================================================
#if(1==USE_USART1)
void USART1_IRQHandler(void)
{  	
	USART_RxIrq(USART1);
}
void DMA1_Channel4_IRQHandler(void)
{
    DMA_ClearFlag(DMA1_FLAG_TC4);
    DMA_Cmd(DMA1_Channel4, DISABLE);
    USART1_TxStruct.TxRunning = 0;
}
#endif

#if(1==USE_USART2)
void USART2_IRQHandler(void)
{
	USART_RxIrq(USART2);
}
void DMA1_Channel7_IRQHandler(void)
{
	DMA_ClearFlag(DMA1_FLAG_TC7);
	DMA_Cmd(DMA1_Channel7, DISABLE);
	USART2_TxStruct.TxRunning = 0;
}
#endif

#if(1==USE_USART3)
void USART3_IRQHandler(void)
{
	USART_RxIrq(USART3);
}
void DMA1_Channel2_IRQHandler(void)
{
	DMA_ClearFlag(DMA1_FLAG_TC2);
	DMA_Cmd(DMA1_Channel2, DISABLE);
	USART3_TxStruct.TxRunning = 0;
}
#endif
//==============================================================================
/*void USART2_RxProc(void)
{
	if(USART2_RxStruct.RxComplete)
	{

        USART_RxStart(USART2);
    }
}*/
//==============================================================================

